
/*****************************************************************************************
 * @file  KeyType.java
 *
 * @author   John Miller
 * @author   Michael Cotterell
 * @author   Paul Duke
 * @version  $Id: KeyType.java 19 2010-06-16 16:08:27Z mepcotterell $
 * @see http://leepoint.net/notes-java/data/expressions/22compareobjects.html
 */

import static java.lang.System.out;

/*****************************************************************************************
 * The KeyType class provides a key type for handling both non-composite and composite keys.
 * A key is a minimal set of attributes that can be used to uniquely identify a tuple.
 */
public class KeyType implements Comparable <KeyType>
{
    /** Array holding the attribute values for a particular key
     */
    private final Comparable [] key;

    /** The number of attributes making up the key
     */
    private final int keySize;

    /*************************************************************************************
     * Construct an instance of KeyType from a tuple.  The key is formed from the first
     * keySize attributes of the tuple.
     * @param tuple     the tuple containing attribute values
     * @param _keySize  the number of attributes to extract from the tuple
     */
    public KeyType (Comparable [] tuple, int _keySize)
    {
         keySize = _keySize;
         key     = new Comparable [keySize];
         for (int i = 0; i < keySize; i++) key [i] = tuple [i];
    } // constructor

    /*************************************************************************************
     * Compare two keys (negative => less than, zero => equals, positive => greater than).
     * @param k  the other key (to compare with this)
     * @return  resultant integer that's negative, zero or positive
     */
    @SuppressWarnings("unchecked")
    public int compareTo (KeyType k)
    {
        for (int i = 0; i < keySize; i++) {
            if (key [i].compareTo (k.key [i]) < 0) return -1;
            if (key [i].compareTo (k.key [i]) > 0) return 1;
        } // for
        return 0;
    } // compareTo

    /*************************************************************************************
     * Determine whether two keys are equal (equals must agree with compareTo).
     * @param k  the other key (to compare with this)
     * @return  true if equal, false otherwise
     */
    public boolean equals (KeyType k)
    {
        return compareTo (k) == 0;
    } // equals

    /*************************************************************************************
     * Compute a hash code for this object (equal objects should produce the same hash code).
     * @return  an integer hash code value
     */
    public int hashCode ()
    {
        int sum = 0;
        for (int i = 0; i < keySize; i++) sum = 7 * sum + key [i].hashCode ();
        return sum;
    } // hashCode

    /*************************************************************************************
     * Convert the key to a string.
     * @return  the string representation of the key
     */
    public String toString ()
    {
        String s = "Key (";
        for (int i = 0; i < keySize; i++) s += " " + key [i];
        return s + (" )");
    } // toString

    /*************************************************************************************
     * The main method is used for testing purposes only.
     * @param args  the command-line arguments
     */
    /*public static void main (String [] args)
    {
        Comparable [] tuple1 = { "Star_Wars_2", 1980, 124, "T", "Fox", 12345 };
        Comparable [] tuple2 = { "Rocky", 1985, 200, "T", "Universal", 12125 };

        KeyType key1 = new KeyType (tuple1, 2);
        KeyType key2 = new KeyType (tuple2, 2);
        KeyType key3 = new KeyType (tuple1, 2);

        out.println ();
        out.println ("Test the KeyClass");
        out.println ();
        out.println ("key1 = " + key1);
        out.println ("key2 = " + key2);
        out.println ("key3 = " + key3);
        out.println ();
        out.println ("key1 < key2: "  + (key1.compareTo (key2) < 0));
        out.println ("key1 == key2: " + (key1.compareTo (key2) == 0));
        out.println ("key1 > key2: "  + (key1.compareTo (key2) > 0));
        out.println ();
        out.println ("key2 < key1: "  + (key2.compareTo (key1) < 0));
        out.println ("key2 == key1: " + (key2.compareTo (key1) == 0));
        out.println ("key2 > key1: "  + (key2.compareTo (key1) > 0));
        out.println ();
        out.println ("key1 < key3: "  + (key1.compareTo (key3) < 0));
        out.println ("key1 == key3: " + (key1.compareTo (key3) == 0));
        out.println ("key1 > key3: "  + (key1.compareTo (key3) > 0));
        out.println ();
        out.println ("key1.equals (key2): " + key1.equals (key2));
        out.println ("key1.equals (key3): " + key1.equals (key3));
        out.println ("key1.hashCode () == key2.hashCode (): " + (key1.hashCode () == key2.hashCode ()));
        out.println ("key1.hashCode () == key3.hashCode (): " + (key1.hashCode () == key3.hashCode ()));
    } */ // main

} // KeyType class
